package com.dnbiz.api.sdk.util;

import java.util.Collection;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.dnbiz.api.sdk.util.StringPool.*;

/**
 * <a href="Validator.java.html"><b><i>View Source</i></b></a>
 *
 * @author  Brian Wing Shun Chan
 * @author  Alysa Carver
 * @version $Revision: 1.1.1.1 $
 *
 */
public class Validator {

    public static boolean isAddress(String address) {
        if (isNull(address)) {
            return false;
        }

        char[] c = address.toCharArray();

        for (int i = 0; i < c.length; i++) {
            if ((!isChar(c[i])) &&
                (!isDigit(c[i])) &&
                (!Character.isWhitespace(c[i]))) {

                return false;
            }
        }

        return true;
    }

    public static boolean isChar(char c) {
        return Character.isLetter(c);
    }

    public static boolean isChar(String s) {
        if (isNull(s)) {
            return false;
        }

        char[] c = s.toCharArray();

        for (int i = 0; i < c.length; i++) {
            if (!isChar(c[i])) {
                return false;
            }
        }

        return true;
    }

    public static boolean isDigit(char c) {
        int x = (int) c;

        if ((x >= 48) && (x <= 57)) {
            return true;
        }

        return false;
    }

    public static boolean isDigit(String s) {
        if (isNull(s)) {
            return false;
        }

        char[] c = s.toCharArray();

        for (int i = 0; i < c.length; i++) {
            if (!isDigit(c[i])) {
                return false;
            }
        }

        return true;
    }

    public static boolean isHex(String s) {
        if (isNull(s)) {
            return false;
        }

        return true;
    }

    public static boolean isHTML(String s) {
        if (isNull(s)) {
            return false;
        }

        if (((s.indexOf("<html>") != -1) || (s.indexOf("<HTML>") != -1)) &&
            ((s.indexOf("</html>") != -1) || (s.indexOf("</HTML>") != -1))) {

            return true;
        }

        return false;
    }

    /**
     * <p>Checks if the field is a valid date.  The <code>Locale</code> is
     * used with <code>java.text.DateFormat</code>.  The setLenient method
     * is set to <code>false</code> for all.</p>
     * <p>
     *  使用方法:
     *  boolean vd=Validator.isDate("2003-12-14",Locale.CHINA);
     *  上面返回true，如果将Locale.CHINA改为Locale.US则返回false.
     *  注意!Locale.CHINA的月份序号是1..12,而Locale.US的月份序号是0..11.
     * </p>
     * @param value The value validation is being performed on.
     * @param locale The locale to use for the date format, defaults to the
     * system default if null.
     *//*
    public static boolean isDate(String value, Locale locale) {
        return DateValidator.getInstance().isValid(value, locale);
    }

    *//**
     * <p>Checks if the field is a valid date.  The pattern is used with
     * <code>java.text.SimpleDateFormat</code>.  If strict is true, then the
     * length will be checked so '2/12/1999' will not pass validation with
     * the format 'MM/dd/yyyy' because the month isn't two digits.
     * The setLenient method is set to <code>false</code> for all.</p>
     *
     * @param value The value validation is being performed on.
     * @param datePattern The pattern passed to <code>SimpleDateFormat</code>.
     * @param strict Whether or not to have an exact match of the datePattern.
     *//*
    public static boolean isDate(String value, String datePattern,
                                 boolean strict) {
        return DateValidator.getInstance().isValid(value, datePattern, strict);
    }*/

  /*  public static boolean isGregorianDate(int month, int day, int year) {
        return CalendarUtil.isGregorianDate(month, day, year);
    }

    public static boolean isJulianDate(int month, int day, int year) {
        return CalendarUtil.isJulianDate(month, day, year);
    }*/

    /**
     * @deprecated Use <code>isEmail</code>.
     */
    public static boolean isEmailAddress(String ea) {
        if (isNull(ea)) {
            return false;
        }

        int eaLength = ea.length();

        if (eaLength < 6) {

            // j@j.c

            return false;
        }

        ea = ea.toLowerCase();

        int at = ea.indexOf('@');

        if ((at > 24) || (at == -1) || (at == 0) ||
            ((at <= eaLength) && (at > eaLength - 5))) {

            // 123456789012345678901234@joe.com
            // joe.com
            // @joe.com
            // joe@joe
            // joe@jo
            // joe@j

            return false;
        }

        int dot = ea.lastIndexOf('.');

        if ((dot == -1) || (dot < at) || (dot > eaLength - 3)) {

            // joe@joecom
            // joe.@joecom
            // joe@joe.c

            return false;
        }

        if (ea.indexOf("..") != -1) {

            // joe@joe..com

            return false;
        }

        char[] name = ea.substring(0, at).toCharArray();

        for (int i = 0; i < name.length; i++) {
            if ((!isChar(name[i])) &&
                (!isDigit(name[i])) &&
                (name[i] != '.') &&
                (name[i] != '-') &&
                (name[i] != '_')) {

                return false;
            }
        }

        if ((name[0] == '.') || (name[name.length - 1] == '.') ||
            (name[0] == '-') || (name[name.length - 1] == '-') ||
            (name[0] == '_')) { // || (name[name.length - 1] == '_')) {

            // .joe.@joe.com
            // -joe-@joe.com
            // _joe_@joe.com

            return false;
        }

        char[] host = ea.substring(at + 1, ea.length()).toCharArray();

        for (int i = 0; i < host.length; i++) {
            if ((!isChar(host[i])) &&
                (!isDigit(host[i])) &&
                (host[i] != '.') &&
                (host[i] != '-')) {

                return false;
            }
        }

        if ((host[0] == '.') || (host[host.length - 1] == '.') ||
            (host[0] == '-') || (host[host.length - 1] == '-')) {

            // joe@.joe.com.
            // joe@-joe.com-

            return false;
        }

        // postmaster@joe.com

        if (ea.startsWith("postmaster@")) {
            return false;
        }

        // root@.com

        if (ea.startsWith("root@")) {
            return false;
        }

        return true;
    }

    /**
     * @deprecated Use <code>isEmailAddress</code>.
     */
    public static boolean isValidEmailAddress(String ea) {
        return isEmailAddress(ea);
    }

    public static boolean isName(String name) {
        if (isNull(name)) {
            return false;
        }

        char[] c = name.trim().toCharArray();

        for (int i = 0; i < c.length; i++) {
            if (((!isChar(c[i])) &&
                 (!Character.isWhitespace(c[i]))) ||
                (c[i] == ',')) {

                return false;
            }
        }

        return true;
    }

    public static boolean isNumber(String number) {
        if (isNull(number)) {
            return false;
        }

        char[] c = number.toCharArray();

        for (int i = 0; i < c.length; i++) {
            if (!isDigit(c[i])) {
                return false;
            }
        }

        return true;
    }

    /**
     * support Numeric format:<br>
     * "33" "+33" "033.30" "-.33" ".33" " 33." " 000.000 "
     * @param str String
     * @return boolean
     */
   public static boolean isNumeric(String str) {
       int begin = 0;
       boolean once = true;
       if (str == null || str.trim().equals("")) {
           return false;
       }
       str = str.trim();
       if (str.startsWith("+") || str.startsWith("-")) {
           if (str.length() == 1) {
               // "+" "-"
               return false;
           }
           begin = 1;
       }
       for (int i = begin; i < str.length(); i++) {
           if (!Character.isDigit(str.charAt(i))) {
               if (str.charAt(i) == '.' && once) {
                   // '.' can only once
                   once = false;
               }
               else {
                   return false;
               }
           }
       }
       if (str.length() == (begin + 1) && !once) {
           // "." "+." "-."
           return false;
       }
       return true;
   }


   public static boolean isNull(Object obj) {
       if (obj == null) {
           return true;
       }

       obj = obj.toString().trim();

       if ((obj.equals(StringPool.NULL)) || (obj.equals(StringPool.BLANK))) {
           return true;
       }

       return false;
   }

    public static boolean isNotNull(Object obj) {
        return!isNull(obj);
    }

    /**
     * 是否Long型ID：[<code>id!=null && id != 0</code>]
     * @author HuangFeng(Feb 1, 2010)
     * @param id Long型ID
     */
    public static boolean isLongId(Long id)
    {
       if(isNull(id))
       {
    	   return false;
       }
       else if( 0l >= id)
       {
    	   return false;
       } else {
    	   return true;
       }
    }

    /**
     * 是否Long型ID：[<code>id!=null && id != 0</code>]
     * @author HuangFeng(Feb 1, 2010)
     * @param id Long型ID
     */
    public static boolean isLongId(String id)
    {
       if(isNull(id))
       {
    	   return false;
       }
       else if( 0l >= Long.valueOf(id))
       {
    	   return false;
       } else {
    	   return true;
       }
    }

    public static boolean isNotLongId(Long id)
    {
       return !isLongId(id);
    }

    public static boolean isIntegerId(Integer id)
    {
    	return isLongId(Long.valueOf(id));
    }

    public static boolean isNotIntegerId(Integer id)
    {
    	return isNotLongId(Long.valueOf(id));
    }

    public static boolean isPassword(String password) {
        if (isNull(password)) {
            return false;
        }

        if (password.length() < 4) {
            return false;
        }

        char[] c = password.toCharArray();

        for (int i = 0; i < c.length; i++) {
            if ((!isChar(c[i])) &&
                (!isDigit(c[i]))) {

                return false;
            }
        }

        return true;
    }

    /**
     * 校验两个数是否相等.<br>
     * <b>成真条件：</b>
     * <li>1.第一个参数不为空</li>
     * <li>2.第二个参数不为空</li>
     * <li>3.两个参数用equals判断为true</li>
     * @param str1 需要判断的第一个字符串
     * @param str2 需要判断的第二个字符串
     * @return boolean 两个数是否相等
     * @author jiangjinrong 2009-01-09
     */
    public static boolean isEquals(String str1,String str2){
    return (Validator.isNotNull(str1)&&Validator.isNotNull(str2)&&str1.equals(str2));
    }

    /**
     * 校验两个数是否不相等.<br>
     * <b>成真条件：</b>
     * <li>1.第一个参数为空</li>
     * <li>2.或者第二个参数为空</li>
     * <li>3.或者两个参数用equals判断为false</li>
     * @param str1 需要判断的第一个字符串
     * @param str2 需要判断的第二个字符串
     * @return boolean 两个数是否不相等
     * @author jiangjinrong 2009-01-09
     */
    public static boolean isNotEquals(String str1,String str2){
    return (Validator.isNull(str1)||Validator.isNull(str2)||!str1.equals(str2));
    }

    /**
     * 判断Map集合是否为Null或isEmpty
     * @author HuangFeng(2009-10-21)
     * @param map Map
     * @return <code>true</code>->isEmpty, <code>false</code>->isNotEmpty
     */
    public static boolean isEmpty(Map<?, ?> map)
    {
    	if(null == map || map.isEmpty())
    	{
    		return true;
    	}
    	return false;
    }

    /**
     * 判断Map集合不为Null或isEmpty
     * @author HuangFeng(2009-10-21)
     * @param map Map
     * @return <code>true</code>->isNotEmpty, <code>false</code>->isEmpty
     */
    public static boolean isNotEmpty(Map<?, ?> map)
    {
    	return !isEmpty(map);
    }

    /**
     * 判断Collection集合类包括子类List,Set是否为Null或isEmpty
     * @author HuangFeng(2009-10-21)
     * @param coll Collection及子类：<code>List</code>, <code>Set</code>
     * @return <code>true</code>->isEmpty, <code>false</code>->isNotEmpty
     */
    public static boolean isEmpty(Collection<?> coll)
    {
    	if(null == coll || coll.isEmpty() || coll.size() == 0)
    	{
    		return true;
    	}
    	return false;
    }

    /**
     * 判断Collection集合类包括子类List,Set为为Null或isEmpty
     * @author HuangFeng(2009-10-21)
     * @param coll Collection及子类：<code>List</code>, <code>Set</code>
     * @return <code>true</code>->isNotEmpty, <code>false</code>->isEmpty
     */
    public static boolean isNotEmpty(Collection<?> coll)
    {
    	return !isEmpty(coll);
    }

    /** URL地址正则表达式 */
    public static final String RPX = "([\\w-]+\\.)+[\\w-]+.([^a-z])(/[\\w- ./?%&=]*)?|[a-zA-Z0-9\\-\\.][\\w-]+.([^a-z])(/[\\w- ./?%&=]*)?";

    /** 域名后缀正则表达式 */
    public static final String DOMAIN_PIX = "(\\.[a-z]{2,5})";

    /** Email REG */
    public static final String EMAIL_REG = "^([-_a-z0-9.])+@([-_a-z0-9]+\\.)+[a-z0-9]{2,3}$";

    /**
     * 文章标题内，不能带有URL，发布时，做判断；有url的话，不允许提交，要求服务器端验证，对抗发帖机器；
     * @author HuangFeng(Feb 5, 2010)
     * @param title 文章标题
     * @return 是否带有URL
     */
	public static boolean isTitle(String title)
	{
		if (isNull(title))
		{
			return false;
		}
		final Pattern TITLE_PATTERN = Pattern.compile(DOMAIN_PIX, Pattern.CASE_INSENSITIVE);
		Matcher matcher = TITLE_PATTERN.matcher(title);
		if(matcher.find())
		{
			return false;
		} else {
			return true;
		}
	}

	/**
	 * EMAIL Validate
	 * @author HuangFeng(Mar 10, 2010)
	 * @param email email
	 * @return Boolean
	 */
	public static final boolean isEmail(final String email)
	{
		return email.matches(EMAIL_REG);
	}

	/**
	 * 判断是否空数组
	 * @param obj
	 * @return
	 */
	public static final boolean isNullArray(Object[] obj){
		if(obj==null||obj.length==0)
			return true;
		return false;
	}

	/**
	 * 判断非否空数组
	 * @param obj
	 * @return
	 */
	public static final boolean isNOtNullArray(Object[] obj){
		return !isNullArray(obj);
	}

	/**
	 * <pre>
	 * 判断是否图片（暂用）
	 * 支持后缀：jpeg, bmp, jpg, png, gif, tbi
	 * </pre>
	 * @author HuangFeng(Mar 25, 2010)
	 * @param image 图片名称
	 * @return 是否图片
	 */
	public static final boolean isImage(String image)
	{
		if(isNull(image))
		{
			return false;
		}
		image = image.toLowerCase();
		if(image.lastIndexOf(JPEG) != -1 || image.lastIndexOf(BMP) != -1 ||
				image.lastIndexOf(JPG) != -1 || image.lastIndexOf(PNG) != -1 ||
				image.lastIndexOf(GIF) != -1 || image.lastIndexOf(TBI) != -1)
		{
			return true;
		} else {
			return false;
		}
	}

	public static void main(String[] args) {

		//String rpx = "[.com]?";
		//final Pattern TITLE_PATTERN = Pattern.compile("([\\w-]+\\.)");
		//Matcher matcher = TITLE_PATTERN.matcher("dsdhttp://");
		//System.out.println(Validator.isTitle("妈妈的.1212sdsdsds"));
		/*
		 *					 while (stBody.hasMoreTokens()) {
								String codeline = stBody.nextToken();
								if (codeline.indexOf("href") != -1) {
									Pattern pattern = Pattern.compile("([^<a]href=[\"\'])(.+?)([\"\'][^a>])");
									Matcher matcher = pattern.matcher(codeline);
									while (matcher.find()) {
									     String matchString  = " href=\""+B2CShop.getAppConfig().getMediaRoot()+"/trace.html?id="+emailSendLog.getId()+"&url="+matcher.group(2)+"\" ";
									     codeline = StringUtils.replace(codeline, matcher.group(), matchString);
									}

								}
		 */

		System.out.println("1:" + isEmail("oursky@qq.com"));
		System.out.println("2:" + isEmail("java@1.qq.com"));
		System.out.println("3:" + isEmail("java@1_qq.com"));
		System.out.println("4:" + isEmail("java@1-qq.com"));
		System.out.println("5:" + isEmail("java-12@1-qq.com"));
		System.out.println("6:" + isEmail("java@12@1-qq.com"));
		System.out.println("7:" + isEmail("java@12@1-qq-cc.com"));
		System.out.println("8:" + isEmail("www.353@365.com"));
		System.out.println("9:" + isEmail("www.3-53@365.com"));
	}
}
